import { defineStore } from "pinia";
import { useNotification } from "./useNotification";
import { AccessData } from "@/apis/types/ApiData";
import { userRefreshToken } from "@/apis/auth";
import { camera, cameraAccount, processAll, processConfiguration, userAuth, userUserInfo } from "@/apis/user";
import { cameraFilesName, cameraUploadFile } from "@/apis/oss";
import { cameraList, deviceCapture, tokenGet } from "@/apis/ezviz";
import { baseURL } from "@/configs/jy";
import { datetimeFormat } from "@/utils/date";
import { deepClone, getImageFile } from "@/utils/conversion";
import default_user_info from "@/assets/data/default_user_info.json";
import default_process from "@/assets/data/default_process.json";

export type SensorType = "AI" | "AO" | "DI" | "DO";
export type Mode = "light" | "dark";
export type Theme = "default" | "custom" | "blue";
export type Custom = {
    color1: string;
    color2: string;
    color3: string;
    color4: string;
    color5: string;
    color6: string;
    color7: string;
    color8: string;
    color9: string;
    color10: string;
    color11: string;
    color12: string;
};
export type FilterItem = {
    name: string;
    visible: boolean;
    isDisplayedInToolbar: boolean;
    items: {
        targetKey: "equipName" | "equipGroup" | "equipType" | "channelName" | "channelUnit" | "channelValue" | "online" | "alarm" | "createTime";
        condition: "includes" | "==" | ">" | "<" | "><";
        targetValue: string;
        targetValue2: string;
        targetValue3: string;
    }[];
};
export type Param = {
    pc_front: {
        map: {
            lng: number;
            lat: number;
            zoom: number;
            style: "default" | "black" | "indigo";
            showEquipLabel: boolean;
            filters: FilterItem[];
        };
    };
    pc_admin: { ui: { mode: Mode; theme: Theme; custom: Custom } };
    app: { ui: { mode: Mode; theme: Theme; custom: Custom } };
};
export type UserInfo = {
    authority: number;
    ddid: string;
    description: string;
    email: string;
    id: number;
    param: Param;
    phone: string;
    qq: string;
    qqunionid: string;
    status: { [propName: string]: any };
    usrid: string;
    usrname: string;
    wx: string;
    wxopenid: string;
    wxunionid: string;
};
export type CameraAccountAccinfo = {
    userName?: string; // -----旧
    AppSecret?: string; // -----旧
    title?: string; // 账户名称
    appKey?: string; // appKey
    appSecret?: string; // appSecret
};
export type CameraAccount = {
    fID: string; // 编辑、删除时使用的fid
    acctype: "hk" | "海康"; // 账户类型
    acckey: string; // 编辑时用的acckey（-----旧AppKey）
    accinfo: CameraAccountAccinfo;
    createDate: string;
    createUserID: string;
    fUserID: string;
    modifyDate: string;
    modifyUserID: string;
};
export type CameraServiceCamerainfo = {
    userName?: string; // 服务名称（-----旧）
    appType?: ""; // （-----旧）
    deviceSerial?: string; // -----旧
    channelNo?: number; // -----旧
    appKey?: string; // -----旧
    appSecret?: string; // -----旧
    fAutoPlay?: number; // -----旧
    fAutoPlayTime?: number; // -----旧
    fCameraPwd?: string; // -----旧
    fCameraType?: number; // -----旧
    fClear?: number; // -----旧
    fSound?: number; // -----旧
    Cycle_Day?: number[]; // -----旧
    Cycle_Timing?: number; // -----旧
    title?: string;
    cameraAccountId?: string;
    cameraId?: string;
    protocol?: number;
    code?: string;
    url?: string;
};
export type CameraService = {
    fID: string; // （编辑、删除时使用的fid）
    cameratype: "hk" | "url";
    cameraid: string; // （编辑时用的cameraid）
    camerainfo: CameraServiceCamerainfo;
    createDate: string;
    createUserID: string;
    fUserID: string;
    invalidtime: string;
    maxcnt: number;
    modifyDate: string;
    modifyUserID: string;
    photos: { src: string; time: number }[];
};
type HKCamera = {
    cameraAccountId: string;
    appKey: string;
    appSecret: string;
    id: string;
    channelName: string; // 通道名
    channelNo: number;
    deviceSerial: string;
    isAdd: number; // 0:隐藏，1:显示
    isEncrypt: number; // 是否加密，0：不加密，1：加密
    isShared: string;
    permission: number; // 分享设备的权限字段
    picUrl: string; // 图片地址（大图），若在萤石客户端设置封面则返回封面图片，未设置则返回默认图片
    status: number; // 在线状态：0-不在线，1-在线（该字段已废弃）
    videoLevel: number; // 视频质量：0-流畅，1-均衡，2-高清，3-超清
};
type ProcessConfig = {
    access: { enable: boolean; config: AccessData[] };
    fName: { enable: boolean; config: string };
    fGroup: { enable: boolean; config: string };
    aiSensor: {
        enable: boolean;
        config: {
            fAIName: string;
            fAIUNIT: string;
            fAlarmL: string;
            fAlarmH: string;
            fAIX1: string;
            fAIX2: string;
            fAIY1: string;
            fAIY2: string;
            fAIImg: string;
            fAIAlarmImg: string;
        };
    };
    aoSensor: {
        enable: boolean;
        config: {
            fAOName: string;
            fAOUNIT: string;
            fAOMin: string;
            fAOMax: string;
            fAOX1: string;
            fAOX2: string;
            fAOY1: string;
            fAOY2: string;
            fAOImg: string;
        };
    };
    diSensor: {
        enable: boolean;
        config: {
            fDIName: string;
            fAlarmDI: string;
            fAlarmDIH: string;
            fDIOnImg: string;
            fDIOffImg: string;
        };
    };
    doSensor: {
        enable: boolean;
        config: {
            fDOName: string;
            fDOOnImg: string;
            fDOOffImg: string;
            fDOUIMode: string;
        };
    };
    fParam: { basicParam: { enable: boolean; config: Equip.BasicParamConfig } };
    fCamera: { enable: boolean; config: Equip.FCamera[] };
    dlc: {
        dam: {
            rtc: { enable: boolean; config: any[] };
            ai: { enable: boolean; config: any[] };
            di: { enable: boolean; config: any[] };
            scene: { enable: boolean; config: any[] };
            scene2: { enable: boolean; config: any[] };
            mb: { enable: boolean; config: any[] };
            dl645: { enable: boolean; config: any[] };
        };
    };
};
type Process = {
    id: number;
    fUNID: string;
    fUserID: string;
    fName: string;
    icon: string;
    flowIndex: number;
    category1: string;
    category2: string;
    flowLabel: string;
    description: string;
    info: {
        processTime: string;
        address: string;
    };
    configurationData: ProcessConfig;
};

export const useUser = defineStore("user", {
    state() {
        return {
            accessToken: "",
            refreshToken: "",
            userInfo: deepClone(default_user_info) as UserInfo,
            cameraAccounts: [] as CameraAccount[],
            cameraServices: [] as CameraService[],
            hkCameras: [] as HKCamera[],
            processes: [] as Process[],
        };
    },
    actions: {
        setState({ accessToken, refreshToken, userInfo }: { accessToken?: string; refreshToken?: string; userInfo?: UserInfo }) {
            if (accessToken !== void 0) {
                this.accessToken = accessToken;
                localStorage.setItem("access_token", accessToken);
            }
            if (refreshToken !== void 0) {
                this.refreshToken = refreshToken;
                localStorage.setItem("refresh_token", refreshToken);
            }
            if (userInfo !== void 0) {
                this.userInfo = userInfo;
                localStorage.setItem("user_info", JSON.stringify(userInfo));
            }
        },
        restoreState() {
            this.accessToken = "";
            this.refreshToken = "";
            this.userInfo = deepClone(default_user_info as typeof this.userInfo);
            this.cameraAccounts.length = 0;
            this.cameraServices.length = 0;
            this.hkCameras.length = 0;
        },
        // 同步token
        syncToken() {
            return new Promise(async (resolve, reject) => {
                try {
                    let { data } = await userRefreshToken({ refreshtoken: localStorage.getItem("refresh_token") || "" });
                    if (data.code !== 200 || !data.data) throw new Error();
                    this.setState({ accessToken: data.data.accesstoken, refreshToken: data.data.refreshToken });
                    resolve(null);
                } catch (err) {
                    reject(err);
                }
            });
        },
        // 同步用户信息
        syncUserInfo() {
            return new Promise(async (resolve) => {
                const notification = useNotification();
                performance.mark("userInfoStart");
                let { data } = await userUserInfo();
                if (data.code === 200) {
                    let userInfo = data.data;
                    userInfo.param = JSON.parse(userInfo.param || "{}");
                    userInfo.status = JSON.parse(userInfo.status || "{}");
                    if (!userInfo.param) userInfo.param = deepClone(default_user_info.param);
                    if (!userInfo.param.pc_front) userInfo.param.pc_front = deepClone(default_user_info.param.pc_front);
                    if (!userInfo.param.pc_front.map) userInfo.param.pc_front.map = deepClone(default_user_info.param.pc_front.map);
                    if (userInfo.param.pc_front.map.style === void 0) userInfo.param.pc_front.map.style = deepClone(default_user_info.param.pc_front.map.style);
                    if (userInfo.param.pc_front.map.zoom === void 0) userInfo.param.pc_front.map.zoom = deepClone(default_user_info.param.pc_front.map.zoom);
                    if (userInfo.param.pc_front.map.lng === void 0) userInfo.param.pc_front.map.lng = deepClone(default_user_info.param.pc_front.map.lng);
                    if (userInfo.param.pc_front.map.lat === void 0) userInfo.param.pc_front.map.lat = deepClone(default_user_info.param.pc_front.map.lat);
                    if (!userInfo.param.pc_front.map.filters) userInfo.param.pc_front.map.filters = deepClone(default_user_info.param.pc_front.map.filters);
                    if (!userInfo.param.pc_admin) userInfo.param.pc_admin = deepClone(default_user_info.param.pc_admin);
                    if (!userInfo.param.app) userInfo.param.app = deepClone(default_user_info.param.app);
                    if (!userInfo.status.weatherCode) userInfo.status = deepClone(default_user_info.status);
                    this.setState({ userInfo });
                    if (!this.userInfo.id) await userAuth();
                    performance.mark("userInfoEnd");
                    performance.measure("userInfoDone", "userInfoStart", "userInfoEnd");
                    const measure = performance.getEntriesByName("userInfoDone")[0];
                    notification.addNotice({ id: notification.notices.length.toString(), type: "performance", title: "性能参数", message: "用户信息同步成功，用时：" + measure?.duration.toFixed(1) + "ms", state: 0, date: Date.now() });
                    performance.clearMarks("userInfoStart");
                    performance.clearMarks("userInfoEnd");
                    performance.clearMeasures("userInfoDone");
                    resolve(null);
                }
            });
        },
        // 同步摄像头信息
        syncCameras() {
            return new Promise(async (resolve) => {
                const notification = useNotification();
                performance.mark("cameraStart");
                let { data: accountData } = await cameraAccount();
                let { data: serviceData } = await camera();
                if (accountData.code === 200 && serviceData.code === 200) {
                    this.cameraAccounts = accountData.data.map((account: any) => {
                        account.accinfo = JSON.parse(account.accinfo);
                        return account;
                    });
                    this.cameraServices = serviceData.data.map((v: any) => {
                        v.camerainfo = JSON.parse(v.camerainfo);
                        v.photos = [];
                        return v;
                    });
                    // 根据摄像头账号类型做处理
                    this.hkCameras.length = 0;
                    for (let i = 0; i < this.cameraAccounts.length; i++) {
                        const account = this.cameraAccounts[i];
                        switch (account.acctype) {
                            // 处理海康
                            case "海康":
                            case "hk": {
                                let { data: tokenData } = await tokenGet({ appKey: account.acckey, appSecret: account.accinfo.AppSecret || "" });
                                if (tokenData && tokenData.code == 200) {
                                    let { data: devicesData } = await cameraList({ accessToken: tokenData.data.accessToken, pageStart: 0, pageSize: 50 });
                                    if (devicesData && devicesData.code == 200) {
                                        this.hkCameras.push(
                                            ...devicesData.data.map((v: HKCamera) => {
                                                v.cameraAccountId = account.fID;
                                                v.appKey = account.acckey;
                                                v.appSecret = account.accinfo.AppSecret || "";
                                                return v;
                                            })
                                        );
                                    }
                                } else notification.addNotice({ id: notification.notices.length.toString(), type: "warn", title: "海康摄像头异常", message: tokenData.msg, state: 0, date: Date.now() });
                                break;
                            }
                        }
                    }
                    console.log("cameraState", this.cameraAccounts, this.cameraServices, this.hkCameras);
                    await this.syncCameraPhotos().catch((err) => console.error(err));
                    performance.mark("cameraEnd");
                    performance.measure("cameraDone", "cameraStart", "cameraEnd");
                    const measure = performance.getEntriesByName("cameraDone")[0];
                    notification.addNotice({ id: notification.notices.length.toString(), type: "performance", title: "性能参数", message: "摄像头信息同步成功，用时：" + measure?.duration.toFixed(1) + "ms", state: 0, date: Date.now() });
                    performance.clearMarks("cameraStart");
                    performance.clearMarks("cameraEnd");
                    performance.clearMeasures("cameraDone");
                    resolve(null);
                }
            });
        },
        async syncCameraPhotos() {
            return new Promise((resolve, reject) => {
                this.cameraServices.forEach(async (cameraService) => {
                    if (cameraService.cameratype == "hk") {
                        let { data } = await cameraFilesName({ cameratype: "hk", deviceserial: cameraService.camerainfo.deviceSerial || "", channelno: cameraService.camerainfo.channelNo || "" });
                        if (data.code == 200) {
                            cameraService.photos = (data.data as string[])
                                .map((v: string) => {
                                    const str = v.match(/\/(\d+)\..+$/)?.[1] || "197001010000";
                                    const time = new Date(str.slice(0, 4) + "-" + str.slice(4, 6) + "-" + str.slice(6, 8) + " " + str.slice(8, 10) + ":" + str.slice(10, 12) + ":00").getTime();
                                    return { src: baseURL + "/jyapp/" + v, time };
                                })
                                .sort((a, b) => Number(b.src.match(/\/(\d+)\..+$/)?.[1] || 0) - Number(a.src.match(/\/(\d+)\..+$/)?.[1] || 0));
                            resolve(null);
                        } else reject("同步照片错误");
                    }
                });
            });
        },
        async checkCameraServicePhotos() {
            try {
                for (let i = 0; i < this.cameraServices.length; i++) {
                    const cameraService = this.cameraServices[i];
                    switch (cameraService.cameratype) {
                        case "hk": {
                            if (cameraService.camerainfo.fCameraType != 1) continue;
                            const lastestDate = cameraService.photos[0]?.time || 0;
                            const takePhoto = async () => {
                                let { data: tokenData } = await tokenGet({ appKey: cameraService.camerainfo.appKey || "", appSecret: cameraService.camerainfo.appSecret || "" });
                                if (tokenData.code == 200) {
                                    let { data: photoData } = await deviceCapture({ accessToken: tokenData.data.accessToken, deviceSerial: cameraService.camerainfo.deviceSerial || "", channelNo: cameraService.camerainfo.channelNo || 0 });
                                    if (photoData && photoData.code == 200) {
                                        const file = await getImageFile(photoData.data.picUrl, datetimeFormat(Date.now(), "YMDhm") + ".jpg");
                                        await cameraUploadFile({ cameratype: "hk", deviceSerial: cameraService.camerainfo.deviceSerial || "", channelNo: cameraService.camerainfo.channelNo || 0, file });
                                    } else throw new Error("抓拍错误");
                                } else throw new Error("萤石token错误");
                            };
                            if (cameraService.camerainfo.Cycle_Timing && Number(cameraService.camerainfo.Cycle_Timing)) {
                                // 处理拍照时间间隔
                                if (Math.floor((Date.now() - lastestDate) / 60000) > cameraService.camerainfo.Cycle_Timing) {
                                    await takePhoto();
                                    await this.syncCameraPhotos().catch((err) => console.error(err));
                                }
                            }
                            const passedMinutes = Math.floor((new Date().getTime() - new Date().setHours(0, 0, 0, 0)) / 60000);
                            const lastestDatePassedMinutes = Math.floor((lastestDate - new Date().setHours(0, 0, 0, 0)) / 60000);
                            for (let i = 0; i < cameraService.camerainfo.Cycle_Day!.length; i++) {
                                // 处理定时拍照
                                if (cameraService.camerainfo.Cycle_Day![i] <= passedMinutes && lastestDatePassedMinutes < cameraService.camerainfo.Cycle_Day![i]) {
                                    await takePhoto();
                                    await this.syncCameraPhotos().catch((err) => console.error(err));
                                }
                            }
                            break;
                        }
                    }
                }
                return null;
            } catch (err) {
                console.error(err);
                return null;
            }
        },
        syncProcesses() {
            return new Promise(async (resolve) => {
                const { data: processesData } = await processAll();
                if (processesData.code == 200) {
                    this.processes.length = 0;
                    this.processes.push(
                        ...processesData.data.map((v: any) => {
                            v.info = JSON.parse(v.info);
                            v.processConfigData = deepClone(default_process.configurationData);
                            return v;
                        })
                    );
                }
                console.log("process", this.processes);
                resolve(null);
            });
        },
        syncProcessDetail(id: number) {
            return new Promise(async (resolve, reject) => {
                const process = this.processes.find((v) => v.id == id);
                if (process) {
                    const { data } = await processConfiguration({ id });
                    const processConfig = JSON.parse(data.data) as ProcessConfig;
                    process.configurationData = processConfig;
                    resolve(null);
                } else reject();
            });
        },
    },
});
